package controller.editor;

import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;

import main.model.Attribute;
import view.editor.AttributeCreationView;
import controller.ButtonColumn;
import controller.ComponentController;
import controller.Controller;

public class AttributeCreationController extends Controller implements ComponentController{

	private AttributeCreationView view;
	private ComponentController componentController;
	private EditorController editorController;
	private Attribute attribute;
	private HashMap<String, Attribute> attributeMap;
	private int attBeingEdited;
	private List<String> attsNames;
	
	public AttributeCreationController(ComponentController controller, EditorController editorController){
		attributeMap = new HashMap<String, Attribute>();
		this.attribute = new Attribute();
		this.componentController = controller;
		this.editorController = editorController;
		this.setAttsNames(new ArrayList<String>());
	}
	
	@Override
	public void displayView() {
		this.view = new AttributeCreationView(this, null);
		this.view.show();	
	}
	
	public void displayEditView(Attribute a) {
		this.view = new AttributeCreationView(this, a);
		this.view.show();	
		this.view.fillAttrData();
	}
	
	public void handleButtonTerminar(){
		if (!"".equals(this.view.getAttributeName())){
			this.attribute.setName(this.view.getAttributeName());
			Pattern p = Pattern.compile("\\((\\w),(\\w)\\)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
			Matcher m = p.matcher(this.view.getSelectedCardinalidad());
			String min, max;
			if (m.find()){
				min = m.group(1);
				max = m.group(2);
				this.attribute.setCardinality(min, max);
			}
			this.attribute.removeAllAttributes();
			for(String s : this.attributeMap.keySet()){
				this.attribute.addAttribute(this.attributeMap.get(s));
			}
			if (this.view.getSelectedType().equals(Attribute.derivadoxcalc)){
				this.attribute.setType(Attribute.derivadoxcalc);
			} else if (this.view.getSelectedType().equals(Attribute.derivadoxcopia)){
				this.attribute.setType(Attribute.derivadoxcopia);
			} else {
				this.attribute.setType(Attribute.caraterizacion);
			}
			if (this.view.getAttr() != null){
				this.componentController.updateAttribute(this.attribute);
			} else {
				this.componentController.addAttributeToComponent(this.attribute);
			}
		} else {
			JDialog dialogo = new JDialog(); 
			JOptionPane.showMessageDialog(dialogo,"No puede generar un atributo sin nombre", "Notificacion",
	                    JOptionPane.INFORMATION_MESSAGE);
		}
		this.view.hide();
	}

	public void handleAddAtribute() {
		AttributeCreationController controller = new AttributeCreationController(this, this.editorController);
		controller.displayView();
	}

	@SuppressWarnings({ "unchecked", "rawtypes", "serial", "unused" })
	@Override
	public void addAttributeToComponent(Attribute att) {
		String name = att.getName();
		if (this.attsNames.contains(name)){
			JDialog dialogo = new JDialog(); 
			JOptionPane.showMessageDialog(dialogo,"Ya existe un atributo con ese nombre", "Notificacion",
					JOptionPane.INFORMATION_MESSAGE);
		} else {
			this.attributeMap.put(name, att);
			Vector rowData = new Vector(0);
			rowData.insertElementAt(name,0);
			this.view.getAttributesToAttr().addRow(rowData);
			int cant_row = this.view.getAttributesToAttr().getRowCount() - 1 ;
			((Vector) this.view.getAttributesToAttr().getDataVector()
					.elementAt(cant_row)).setElementAt("Editar", 1);
			((Vector) this.view.getAttributesToAttr().getDataVector()
					.elementAt(cant_row)).setElementAt("Borrar", 2);

			Action edit = new AbstractAction()
			{
			    public void actionPerformed(ActionEvent e)
			    {
			        editAttribute();
			    }
			};
			Action delete = new AbstractAction()
			{
			    public void actionPerformed(ActionEvent e)
			    {
			    	deleteAttribute();
			    }
			};

			ButtonColumn editColumn = new ButtonColumn(this.view.getTablaAtributos(), edit, 1);
			ButtonColumn deleteColumn = new ButtonColumn(this.view.getTablaAtributos(), delete, 2);
			this.attributeMap.put(name, att);
			this.attsNames.add(name);
		}
	}
	
	@SuppressWarnings("rawtypes")
	public void editAttribute(){
		int[] rows = this.view.getTablaAtributos().getSelectedRows();
		int index = rows[0];
		String atribut = ((Vector) this.view.getAttributesToAttr().getDataVector()
				.elementAt(index)).elementAt(0).toString();
		Attribute a = this.attributeMap.get(atribut);
		this.attBeingEdited = index;
		AttributeCreationController attController = new AttributeCreationController(this, this.editorController);
		attController.displayEditView(a);
	}
	
	@SuppressWarnings("rawtypes")
	public void deleteAttribute(){
		DefaultTableModel model = (DefaultTableModel) this.view.getAttributesToAttr();
		int[] rows = this.view.getTablaAtributos().getSelectedRows();
		int index = rows[0];
		String atribut = ((Vector) this.view.getAttributesToAttr().getDataVector()
				.elementAt(index)).elementAt(0).toString();
		this.attributeMap.remove(atribut);
		model.removeRow(index);
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public void updateAttribute(Attribute attribute) {
		String atribut = ((Vector) this.view.getAttributesToAttr().getDataVector()
				.elementAt(this.attBeingEdited)).elementAt(0).toString();
		Attribute removedAttr = this.attributeMap.remove(atribut);
		this.editorController.bindPointsToNewComponent(removedAttr, attribute);
		this.attributeMap.put(attribute.getName(), attribute);
		((Vector) this.view.getAttributesToAttr().getDataVector()
				.elementAt(this.attBeingEdited)).setElementAt(attribute.getName(), 0);
		this.view.getAttributesToAttr().fireTableDataChanged();
		
	}

	public void setAttsNames(List<String> attsNames) {
		this.attsNames = attsNames;
	}

	public List<String> getAttsNames() {
		return attsNames;
	}

}
